import { Injectable, NotFoundException } from '@nestjs/common'
import { InjectRepository } from '@nestjs/typeorm'
import { isNil } from 'lodash'
import { Repository } from 'typeorm'
import { paginate } from '~/helper/paginate'
import { Pagination } from '~/helper/paginate/pagination'
import { CreateBookDto } from '../dto/create-book.dto'
import { QueryBookDto } from '../dto/query-book.dto'
import { UpdateBookDto } from '../dto/update-book.dto'
import { BookEntity } from '../entities/book.entity'
import { BookTagEntity } from '../entities/book-tag.entity'

@Injectable()
export class BookService {
  constructor(
    @InjectRepository(BookEntity)
    private readonly bookRepository: Repository<BookEntity>,
    @InjectRepository(BookTagEntity)
    private readonly bookTagRepository: Repository<BookTagEntity>,
  ) {}

  /**
   * 创建书籍
   */
  async create(createBookDto: CreateBookDto) {
    const book = this.bookRepository.create(createBookDto)
    return this.bookRepository.save(book)
  }

  /**
   * 查询书籍列表（分页）
   */
  async findAll(query: QueryBookDto): Promise<Pagination<BookEntity>> {
    const { page, pageSize, bookName, bookGrade, tagId } = query

    const queryBuilder = this.bookRepository
      .createQueryBuilder('book')
      .leftJoinAndSelect('c_book_tag', 'tag', 'book.bookTagId = tag.id')
      .where('book.isDelete = :isDelete', { isDelete: 0 })

    // 添加筛选条件
    if (bookName) {
      queryBuilder.andWhere('book.bookName LIKE :bookName', { bookName: `%${bookName}%` })
    }

    if (!isNil(bookGrade)) {
      queryBuilder.andWhere('book.bookGrade = :bookGrade', { bookGrade })
    }

    if (!isNil(tagId)) {
      queryBuilder.andWhere('book.bookTagId = :tagId', { tagId })
    }

    // 设置需要查询的标签字段
    queryBuilder.addSelect([
      'tag.tag_name as tagName',
    ])

    // 设置默认排序
    queryBuilder.orderBy('book.createdAt', 'DESC')

    return paginate<BookEntity>(queryBuilder, {
      page,
      pageSize,
    })
  }

  /**
   * 查询单个书籍
   */
  async findOne(id: number) {
    const book = await this.bookRepository
      .createQueryBuilder('book')
      .leftJoinAndSelect('c_book_tag', 'tag', 'book.bookTagId = tag.id')
      .where('book.id = :id', { id })
      .andWhere('book.isDelete = :isDelete', { isDelete: 0 })
      .addSelect(['tag.tag_name as tagName'])
      .getOne()

    if (!book) {
      throw new NotFoundException(`书籍ID为${id}的记录不存在`)
    }

    return book
  }

  /**
   * 更新书籍信息
   */
  async update(id: number, updateBookDto: UpdateBookDto) {
    const book = await this.findOne(id)

    return this.bookRepository.save({
      ...book,
      ...updateBookDto,
    })
  }

  /**
   * 删除书籍（逻辑删除）
   */
  async remove(id: number) {
    const book = await this.findOne(id)

    // 逻辑删除
    book.isDelete = 1

    return this.bookRepository.save(book)
  }
}
